package com.smart.mac.config;

import cn.hutool.core.collection.CollectionUtil;
import com.smart.mac.model.vo.UserDemoVO;
import com.smart.mac.utls.LocalSessionUtils;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * flowable 引擎注入封装
 * @author mac
 */
@Component
@Getter
public class FlowServiceConfig {

    @Resource
    protected RepositoryService repositoryService;

    @Resource
    protected RuntimeService runtimeService;

    @Resource
    protected IdentityService identityService;

    @Resource
    protected TaskService taskService;

    @Resource
    protected HistoryService historyService;

    @Resource
    protected ManagementService managementService;

    @Qualifier("processEngine")
    @Resource
    protected ProcessEngine processEngine;


    /**
    * 获取租户流程实例对象
    * @param: [instanceId]
    * @return: org.flowable.engine.runtime.ProcessInstance
    * @author mac
    */
    protected ProcessInstance getTenantProcessInstant(String instanceId){
        Assert.isTrue(StringUtils.isNotEmpty(instanceId),"流程实例ID不能为空");
        //租户ID，TODO: 正式开发从SecurityContext获取就行
        UserDemoVO userDemo = (UserDemoVO) LocalSessionUtils.get();
        String tenantId = userDemo.getCompanyId();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceTenantId(tenantId)
                .processInstanceId(instanceId).singleResult();
        Assert.notNull(processInstance,"流程实例不存在");
        return processInstance;
    }

    /**
    * 获取租户流程定义对象
    * @param: [procDefId, deployId]
    * @return: org.flowable.engine.repository.ProcessDefinition
    * @author mac
    */
    protected ProcessDefinition getTenantProcessDefinition(String procDefId, String deployId){
        Assert.isTrue(!StringUtils.isAllEmpty(procDefId,deployId),"流程实例ID或部署ID不能都为空");
        //租户ID，TODO: 正式开发从SecurityContext获取就行
        UserDemoVO userDemo = (UserDemoVO)LocalSessionUtils.get();
        String tenantId = userDemo.getCompanyId();
        ProcessDefinition processDefinition = null;
        if (StringUtils.isNotEmpty(deployId)){
            processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).processDefinitionTenantId(tenantId)
                    .singleResult();
        }else{
            processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).processDefinitionTenantId(tenantId)
                    .singleResult();
        }
        Assert.notNull(processDefinition,"流程定义不存在");
        return processDefinition;
    }


    /**
    * 获取租户任务ID
    * @param: [taskId]
    * @return: org.flowable.task.api.Task
    * @author mac
    */
    protected Task getTenantTask(String taskId){
        Assert.notNull(taskId,"任务ID不能为空");
        //租户ID，TODO: 正式开发从SecurityContext获取就行
        UserDemoVO userDemo = (UserDemoVO)LocalSessionUtils.get();
        String tenantId = userDemo.getCompanyId();
        Task task = taskService.createTaskQuery().taskId(taskId).taskTenantId(tenantId)
                .singleResult();
        Assert.notNull(task,"任务不存在");
        return task;
    }

    /**
     * 获取租户历史任务
     * @param: [instanceId]
     * @return: java.util.List<org.flowable.task.api.history.HistoricTaskInstance>
     * @author mac
     */
    protected List<HistoricTaskInstance> getTenantHistoricTaskInstanceList(String instanceId){
        Assert.notNull(instanceId,"实例ID不能为空");
        //租户ID，TODO: 正式开发从SecurityContext获取就行
        UserDemoVO userDemo = (UserDemoVO)LocalSessionUtils.get();
        String tenantId = userDemo.getCompanyId();
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).taskTenantId(tenantId)
                .orderByHistoricTaskInstanceStartTime().asc().list();
        return list;
    }

    /**
    * 获取租户历史流程实例
    * @param: [instanceId]
    * @return: org.flowable.engine.history.HistoricProcessInstance
    * @author mac
    */
    protected HistoricProcessInstance getTenantHistoricProcessInstance(String instanceId){
        Assert.notNull(instanceId,"实例ID不能为空");
        //租户ID，TODO: 正式开发从SecurityContext获取就行
        UserDemoVO userDemo = (UserDemoVO)LocalSessionUtils.get();
        String tenantId = userDemo.getCompanyId();
        HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).processInstanceTenantId(tenantId)
                .singleResult();
        Assert.notNull(instance,"历史流程实例不存在");
        return instance;
    }


    /**
    * 获取租户历史活动实例
    * @param: [instanceId]
    * @return: java.util.List<org.flowable.engine.history.HistoricActivityInstance>
    * @author mac
    */
    protected List<HistoricActivityInstance> getTenantHistoricActivityInstance(String instanceId){
        Assert.notNull(instanceId,"实例ID不能为空");
        //租户ID，TODO: 正式开发从SecurityContext获取就行
        UserDemoVO userDemo = (UserDemoVO)LocalSessionUtils.get();
        String tenantId = userDemo.getCompanyId();
        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId)
                .tenantIdIn(Arrays.asList(tenantId))
                .orderByHistoricActivityInstanceStartTime().asc().list();
        Assert.isTrue(CollectionUtil.isNotEmpty(historicActivityInstances),"查询不到历史活动");
        return historicActivityInstances;
    }
    /**
    * 获取租户任务
    * @param: [instanceId]
    * @return: java.util.List<org.flowable.task.api.Task>
    * @author mac
    */
    protected List<Task> getTenantTaskList(String instanceId){
        Assert.notNull(instanceId,"实例ID不能为空");
        //租户ID，TODO: 正式开发从SecurityContext获取就行
        UserDemoVO userDemo = (UserDemoVO)LocalSessionUtils.get();
        String tenantId = userDemo.getCompanyId();
        List<Task> list = taskService.createTaskQuery().processInstanceId(instanceId).taskTenantId(tenantId)
                .orderByTaskCreateTime().desc().list();
        return list;
    }
   /**
   * 执行集合
   * @param: [instanceId]
   * @return: java.util.List<org.flowable.engine.runtime.Execution>
   * @author mac
   */
    protected List<Execution> getTenantExecutionList(String instanceId){
        Assert.notNull(instanceId,"实例ID不能为空");
        //租户ID，TODO: 正式开发从SecurityContext获取就行
        UserDemoVO userDemo = (UserDemoVO)LocalSessionUtils.get();
        String tenantId = userDemo.getCompanyId();
        List<Execution> list = runtimeService.createExecutionQuery().processInstanceId(instanceId).executionTenantId(tenantId).list();
        return list;
    }

    /**
    * 获取租户历史活动数据
    * @param: [instanceId]
    * @return: java.util.List<org.flowable.engine.history.HistoricActivityInstance>
    * @author mac
    */
    protected  List<HistoricActivityInstance> getTenantHistoriActivityList(String instanceId){
        //租户ID，TODO: 正式开发从SecurityContext获取就行
        UserDemoVO userDemo = (UserDemoVO)LocalSessionUtils.get();
        String tenantId = userDemo.getCompanyId();
        List<HistoricActivityInstance> list = historyService
                .createHistoricActivityInstanceQuery()
                .tenantIdIn(Arrays.asList(tenantId))
                .processInstanceId(instanceId)
                .orderByHistoricActivityInstanceStartTime()
                .desc().list();
        return list;
    }

}
